package com.efast.cafe.commponent.es.socketio.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

import com.cafeauto.socketio.SocketIOData;
import com.corundumstudio.socketio.SocketIOClient;

public class SocketIOUtil {
	
	private static final Logger log = LoggerFactory.getLogger(SocketIOUtil.class);
	
	
	private static final String REDIS_MESSAGE_LISTENERS_KEY="REDIS_MESSAGE_LISTENERS_BY_";
	
	public static final String SOCKET_MESSAGE_KEY_="SOCKET_MESSAGE_BY_";
	public static final String SOCKET_DISMESSAGE_KEY_="SOCKET_DISMESSAGE_BY_";
	
	public static final String REDIS_MESSAGE_LISTENER_BEANNAME_PRE="REDIS_MESSAGE_LISTENER_BEANNAME_";
	
	public static final String REDIS_SOCKET_CONNECT_MESSAGE_LISTENER_BEANNAME_PRE="DIS_CON_LISTENER_BEANNAME_";
	
	public static final String REDIS_CURRENT_ONLINE_USERS_KEY="REDIS_CURRENT_ONLINE_USERS_";

	/**
	 * 存放用户的 当前客户端socket io连接
	 */
	private static final ConcurrentHashMap<String, SocketIOClient> currentConnectClients = new ConcurrentHashMap<>();
	
	/**
	 * 当用户连接上socket io服务时，创建对应的redis通道监听器
	 */
	private static final ConcurrentHashMap<String, RedisMessageListenerContainer> currentUserRedisMessageListeners = new ConcurrentHashMap<>();
	
	private static final ConcurrentHashMap<String,RedisMessageListenerContainer> currentUserRedisDisConMessageListeners = new ConcurrentHashMap<>();
	
	private static final ConcurrentHashMap<String, int[]> disconnectIntCounter = new ConcurrentHashMap<String, int[]>();
	
	private static final String totalDisconnectCounterKey = "TOTAL_DISCONNECT_COUNTER";
	
	
	public static void puSocketIOClient(String uid,SocketIOClient client){
		currentConnectClients.put(uid, client);
	}
	
	public static List<SocketIOClient> getSocketIOClients(List<String> uids){
		List<SocketIOClient> list = new ArrayList<>();
		uids.forEach(uid->{
			SocketIOClient c = getSocketIOClient(uid);
			if(c!=null){
				list.add(c);
			}
		});
		return list;
	}
	
	public static SocketIOClient getSocketIOClient(String uid){
		SocketIOClient client = currentConnectClients.get(uid);
		return client;
	}
	
	
	
	public static void removeClient(String uid){
		currentConnectClients.remove(uid);
	}
	
	public static void removeContainer(String uid){
		currentUserRedisMessageListeners.remove(REDIS_MESSAGE_LISTENERS_KEY+"_"+uid);
	}
	
	public static void removeDisConContainer(String uid){
		currentUserRedisDisConMessageListeners.remove(REDIS_MESSAGE_LISTENERS_KEY+"_"+uid);
	}
	
	/**
	 * 判断某个用户的redis监听器是否存在
	 * @param companyCode
	 * @param username
	 * @return
	 */
	public static boolean listenerContains(String uid){
		return currentUserRedisMessageListeners.containsKey(REDIS_MESSAGE_LISTENERS_KEY+"_"+uid);
	}
	
	public static void putMessageListener(String uid,RedisMessageListenerContainer c){
			currentUserRedisMessageListeners.put(REDIS_MESSAGE_LISTENERS_KEY+"_"+uid, c);
	}
	
	public static RedisMessageListenerContainer getMessageListener(String uid){
		return currentUserRedisMessageListeners.get(REDIS_MESSAGE_LISTENERS_KEY+"_"+uid);
	}
	
	
	public static boolean listenerDisContains(String uid){
		return currentUserRedisDisConMessageListeners.containsKey(REDIS_MESSAGE_LISTENERS_KEY+"_"+uid);
	}
	
	public static void putMessageDisListener(String uid,RedisMessageListenerContainer c){
			currentUserRedisDisConMessageListeners.put(REDIS_MESSAGE_LISTENERS_KEY+"_"+uid, c);
	}
	
	public static RedisMessageListenerContainer getDisMessageListener(String uid){
		return currentUserRedisDisConMessageListeners.get(REDIS_MESSAGE_LISTENERS_KEY+"_"+uid);
	}
	
	public static synchronized void additionDisconnectCounter(String uid){
		int[] valueWrapper = disconnectIntCounter.get(uid);
		if (valueWrapper == null) {
			disconnectIntCounter.put(uid, new int[] { 1 });
        } else {
            valueWrapper[0]++;
        }
	}
	
	public static synchronized void additionAllDisconnectCounter(){
		additionDisconnectCounter(totalDisconnectCounterKey);
	}
	
	public static int countTotalDisconnectCounter(){
		return getDisconnectCounterByUid(totalDisconnectCounterKey);
	}
	
	public static HashMap<String, Integer> countDisconnectCounterByUid(int timers){
		HashMap<String, Integer> res = new HashMap<>();
		disconnectIntCounter.forEach((key,value)->{
			if(!totalDisconnectCounterKey.equals(key) && value[0]>=timers){
				res.put(key, value[0]);
			}
		});
		return res;
	}
	
	private static int getDisconnectCounterByUid(String uid){
		int[] valueWrapper = disconnectIntCounter.get(uid);
		if (valueWrapper == null) {
			return 0;
        } else {
            return valueWrapper[0];
        }
	}
	
	public static void clearAllDisconnectCounter(){
		disconnectIntCounter.clear();
	}
	
}
